package com.jade.gateway.service.impl;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

/**
 * @author Arnold
 * @version V2.0
 * @className DynamicRouteServiceImpl
 * @description 动态路由监听服务
 * @date 2022/01/18 21:12
 **/

@Slf4j
@Service
@AllArgsConstructor
public class DynamicRouteServiceImpl implements ApplicationEventPublisherAware {

    /**
     * 路由写入器
     */
    private final RouteDefinitionWriter routeDefinitionWriter;

    /**
     * 发布事件
     */
    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    /**
     *  删除路由
     * @param id 路由ID
     * @return java.lang.Boolean
     * @author Arnold
     * @date 2022/1/19
     **/
    public Boolean deleteRoute(String id) {
        try {
            log.info("gateway delete route id {}", id);
            routeDefinitionWriter.delete(Mono.just(id)).subscribe();
            this.refreshRouteEvent();
            return true;
        } catch (Exception e) {
            log.error("gateway delete fail");
        }
        return false;
    }

    /**
     *  更新路由
     * @param definition 路由信息
     * @return java.lang.String
     * @author Arnold
     * @date 2022/1/18
     **/
    public Boolean updateRoute(RouteDefinition definition) {
        //先删除路由
        deleteRoute(definition.getId());
        return addRoute(definition);
    }

    /**
     *  增加路由
     * @param definition 路由信息
     * @return java.lang.Boolean
     * @author Arnold
     * @date 2022/1/19
     **/
    public Boolean addRoute(RouteDefinition definition) {
        try {
            log.info("gateway add route {}", definition);
            routeDefinitionWriter.save(Mono.just(definition)).subscribe();
            this.refreshRouteEvent();
            log.info("gateway add success");
            return true;
        } catch (Exception e) {
            log.error("gateway add fail {}", e.getMessage());
            e.printStackTrace();
        }
        return false;
    }

    /**
     *  刷新路由事件
     * @param
     * @return void
     * @author Arnold
     * @date 2022/4/11
     **/
    public void refreshRouteEvent() {
        this.applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this));
    }

}
